<template>
  <div id="container" class="box">
    <div id="cesiumContainer"></div>
  </div>
</template>

<script>
import CesiumZh from "../utils/cesiumlocal"

export default {
  name: "models",
  data() {
    return {
      url: "models/tileset.json",
      // url: "http://www4.skylineglobe.com/SG/b3dm/Hod-Hasharon_Build_3_Entire_2705.1724701/tileset.json",
      Cesium: "",
      viewer: ""
    }
  },
  mounted() {
    this.Cesium = this.cesium
    this.viewer = new this.Cesium.Viewer("cesiumContainer", {
      animation: true, // 默认true  是否创建动画小器件 左下角仪表
      baseLayerPicker: true, // 默认true 是否显示图层选择器
      fullscreenButton: true, // 默认true  是否显示全屏按钮
      vrButton: true, // 默认false 是否显示VR按钮
      geocoder: true, // 默认true 是否显示geocoder小器件，右上角查询按钮
      homeButton : true, // 默认true 是否显示Home按钮
      infoBox: true, // 默认true 是否显示信息框
      sceneModePicker: true, // 默认true 是否显示3D/2D选择器
      selectionIndicator: true, // 默认true 是否显示选取指示器组件
      timeline: true, // 默认true 是否显示时间轴
      navigationHelpButton: true, // 默认true 是否显示右上角的帮助按钮
      scene3DOnly: false, // 默认false 如果设置为true，则所有几何图形以3D模式绘制以节约GPU资源
      shouldAnimate: true, // 默认false true如果默认情况下时钟应该尝试提前模拟时间，false否则
      shadows: false // 默认false 确定阴影是否由光源投射
    }) 
    this.init()
  },
  methods: {
    init() {
      let Cesium = this.Cesium
      var viewer = this.viewer
      Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzYzI1NzcwNS1jZDQ0LTQzZjMtOTIyZC0xMDgzNWNmODVhYmUiLCJpZCI6ODYxODQsImlhdCI6MTY0NzU2OTU5N30.oNBhNr4HdFDhGrxYbHX0qdxVpFLIhlVtXmsW6oSr9Y4"

      var providerViewModels = []

      let gaodev = new Cesium.UrlTemplateImageryProvider({
        url: "http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
        subdomains: ["1", "2", "3", "4"]
      })
      var gaodeMapModel = new Cesium.ProviderViewModel({
        name: "高德矢量",
        iconUrl: Cesium.buildModuleUrl(
          "Widgets/Images/ImageryProviders/openStreetMap.png"
        ),
        tooltip: "高德矢量 地图服务",
        creationFunction: function() {
          return gaodev
        }
      })
      providerViewModels.push(gaodeMapModel)

      let gaode = new Cesium.UrlTemplateImageryProvider({
        url: "https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
        subdomains: ["1", "2", "3", "4"]
      })
      let gaodeLabel = new Cesium.UrlTemplateImageryProvider({
        url: "http://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}",
        subdomains: ["1", "2", "3", "4"]
      })
      var gaodeMapModel = new Cesium.ProviderViewModel({
        name: "高德影像",
        iconUrl: Cesium.buildModuleUrl(
          "Widgets/Images/ImageryProviders/mapboxSatellite.png"
        ),
        tooltip: "高德影像 地图服务",
        creationFunction: function() {
          return [gaode, gaodeLabel]
        }
      })
      providerViewModels.push(gaodeMapModel)

      let tencent = new Cesium.UrlTemplateImageryProvider({
        url: "https://p2.map.gtimg.com/sateTiles/{z}/{sx}/{sy}/{x}_{reverseY}.jpg?version=229",
        customTags: {
          sx: function(imageryProvider, x, y, level) {
            return x >> 4
          },
          sy: function(imageryProvider, x, y, level) {
            return ((1 << level) - y) >> 4
          }
        }
      })
      let tencentLabel = new Cesium.UrlTemplateImageryProvider({
        url: "https://rt3.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&styleid=2&version=297"
      })
      var gaodeMapModel = new Cesium.ProviderViewModel({
        name: "腾讯影像",
        iconUrl: Cesium.buildModuleUrl(
          "Widgets/Images/ImageryProviders/mapboxSatellite.png"
        ),
        tooltip: "腾讯影像 地图服务",
        creationFunction: function() {
          return [tencent, tencentLabel]
        }
      })
      providerViewModels.push(gaodeMapModel)

      viewer.baseLayerPicker.viewModel.imageryProviderViewModels = providerViewModels

      // 设置默认地图源
      viewer.baseLayerPicker.viewModel.selectedImagery = viewer.baseLayerPicker.viewModel.imageryProviderViewModels[0]

      this.createModel(this.url, viewer, Cesium)

      viewer._cesiumWidget._creditContainer.style.display = "none" // 隐藏版权
      CesiumZh.load() // 汉化
    },
    createModel(url, viewer, Cesium) {
      let tileset = new Cesium.Cesium3DTileset({
        url: url,
        // 控制切片视角显示的数量，可调整性能
        maximumScreenSpaceError: 2, // 最大的屏幕空间误差
        maximumNumberOfLoadedTiles: 100000, // 最大加载瓦片个数
      })

      tileset.readyPromise.then(function (tileset) {
        viewer.scene.primitives.add(tileset)
        // 设置自定义样式
        var heightStyle = new Cesium.Cesium3DTileStyle({
        color:{
            conditions:[
              // ["${material} === null", "color('white')"],
              // ["${material} === 'glass'", "color('skyblue', 0.5)"],
              // ["${material} === 'concrete'", "color('grey')"],
              // ["${material} === 'brick'", "color('indianred')"],
              // ["${material} === 'stone'", "color('lightslategrey')"],
              // ["${material} === 'metal'", "color('lightgrey')"],
              // ["${material} === 'steel'", "color('lightsteelblue')"],
              ["true", "color('skyblue')"], // This is the else case
            ]
          }
        })
        // 将默认样式改为自定义样式
        tileset.style = heightStyle

        var longitude = 113.549608 // 模型需要改变的经度
        var latitude = 34.813093 // 模型需要改变的纬度
        var heightOffset = 0.0 // 模型需要改变的高度

        // ------ 方法一 官方示例 3D Tiles Adjust Height https://sandcastle.cesium.com/?src=3D%20Tiles%20Adjust%20Height.html&label=3D%20Tiles ------//
        // Cartographic： 经纬度坐标系
        // 以地球经纬度和高度来描述点的位置
        // 经度：参考椭球面上某点的大地子午面与本初子午面间的两面角。东正西负。
        // 纬度 ：参考椭球面上某点的法线与赤道平面的夹角。北正南负。
        // Cartesian3：笛卡尔空间直角坐标系

        // 获取3Dtlies的bounds范围
        var boundingSphere = tileset.boundingSphere;
        // 获取3Dtlies的范围中心点的弧度
        var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center)
        // 模型本身的位置
        var surface = Cesium.Cartesian3.fromRadians(
          cartographic.longitude,
          cartographic.latitude,
          0.0
        )
        // 模型改变的位置
        var offsetvalue = Cesium.Cartographic.fromDegrees(longitude, latitude, heightOffset)  // 定义3Dtlies改变之后中心点的弧度
        var offset = Cesium.Cartesian3.fromRadians(
          offsetvalue.longitude,
          offsetvalue.latitude,
          heightOffset
        )
        // 定义模型的改变状态
        var translation = Cesium.Cartesian3.subtract(
          offset,
          surface,
          new Cesium.Cartesian3()
        )
        // 修改模型的位置
        tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)

         // ------ 方法二 ------ //
        var params = {
          scale: 1.0,
          longitude: longitude, //模型中心X轴坐标（经度，单位：十进制度）
          latitude: latitude, //模型中心Y轴坐标（纬度，单位：十进制度）
          height: heightOffset, //模型中心Z轴坐标（高度，单位：米）
          rx: 0, //X轴（经度）方向旋转角度（单位：度）圆心应该是在地心，改动其中一个值的时候，不止变化了该变量，比如改动ry，模型的高度也有了显著上升
          ry: 0, //Y轴（纬度）方向旋转角度（单位：度）
          rz: 0, //Z轴（高程）方向旋转角度（单位：度
        }
        //旋转
        var rotationX = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx))
        var rotationY = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry))
        var rotationZ = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz))
        var rotationTranslationX = Cesium.Matrix4.fromRotationTranslation(rotationX)
        var rotationTranslationY = Cesium.Matrix4.fromRotationTranslation(rotationY)
        var rotationTranslationZ = Cesium.Matrix4.fromRotationTranslation(rotationZ)
        //平移 修改经纬度
        var transformPosition = Cesium.Cartesian3.fromDegrees(params.longitude, params.latitude, params.height)
        var mtx = Cesium.Transforms.eastNorthUpToFixedFrame(transformPosition)
        //旋转、平移矩阵相乘
        Cesium.Matrix4.multiply(mtx, rotationTranslationX, mtx)
        Cesium.Matrix4.multiply(mtx, rotationTranslationY, mtx)
        Cesium.Matrix4.multiply(mtx, rotationTranslationZ, mtx)
        //缩放 修改缩放比例
        var scale = Cesium.Matrix4.fromUniformScale(params.scale)
        Cesium.Matrix4.multiply(mtx, scale, mtx);
        //赋值给tileset
        console.log(tileset)
        // tileset._root.transform = mtx

        viewer.zoomTo(
          tileset,
          new Cesium.HeadingPitchRange(
            0.0,
            -0.5,
            tileset.boundingSphere.radius * 2.0
          )
        )
      }).otherwise(function (error) {
        console.log(error)
      })
    }
  }
}
</script>

<style lang='scss' scoped>
html, body, #cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  position: relative;
}
</style>
